package com.zenithmind.exam.config;

import com.zenithmind.common.security.ResourceServerConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

/**
 * 考试服务安全配置
 * 
 * @author ZenithMind
 * @since 2024-07-01
 */
@Slf4j
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class ExamSecurityConfig extends ResourceServerConfig {

    /**
     * API文档相关端点白名单
     */
    private static final String[] AUTH_WHITELIST = {
        // Swagger UI
        "/swagger-ui/**",
        "/swagger-ui.html",
        "/v3/api-docs/**",
        "/doc.html",
        "/webjars/**",
        
        // Actuator
        "/actuator/**",
        
        // 静态资源
        "/favicon.ico",
        "/error"
    };

    /**
     * 公开端点 - 无需认证
     */
    private static final String[] PUBLIC_ENDPOINTS = {
        // 考试分类公开查询
        "/api/exam/category/tree",
        "/api/exam/category/enabled",
        "/api/exam/category/root",
        
        // 考试公开查询
        "/api/exam/ongoing",
        "/api/exam/upcoming",
        "/api/exam/hot",
        
        // 题目公开查询（不显示答案）
        "/api/exam/question/search",
        "/api/exam/question/frequent-wrong"
    };

    /**
     * 学生角色端点
     */
    private static final String[] STUDENT_ENDPOINTS = {
        // 学生考试相关
        "/api/exam/*/start",
        "/api/exam/*/can-take",
        "/api/exam/*/questions",
        
        // 学生答题相关
        "/api/exam/record/*/submit",
        "/api/exam/record/my-records",
        "/api/exam/record/*/result"
    };

    /**
     * 教师角色端点
     */
    private static final String[] TEACHER_ENDPOINTS = {
        // 考试管理
        "/api/exam",
        "/api/exam/*",
        "/api/exam/*/publish",
        "/api/exam/*/pause",
        "/api/exam/*/resume",
        "/api/exam/*/end",
        "/api/exam/*/copy",
        "/api/exam/my-created",
        "/api/exam/batch",
        "/api/exam/*/statistics/update",
        
        // 题目管理
        "/api/exam/question",
        "/api/exam/question/*",
        "/api/exam/question/*/status",
        "/api/exam/question/batch",
        "/api/exam/question/*/copy",
        "/api/exam/question/*/move",
        "/api/exam/question/import/*",
        "/api/exam/question/export/*",
        
        // 题库管理
        "/api/exam/question-bank",
        "/api/exam/question-bank/*",
        "/api/exam/question-bank/*/status",
        "/api/exam/question-bank/batch",
        
        // 分类管理
        "/api/exam/category",
        "/api/exam/category/*",
        "/api/exam/category/*/status",
        "/api/exam/category/*/can-delete"
    };

    /**
     * 管理员角色端点
     */
    private static final String[] ADMIN_ENDPOINTS = {
        // 系统管理
        "/api/exam/admin/**",
        
        // 统计分析
        "/api/exam/statistics/**",
        
        // 数据导入导出
        "/api/exam/data/**"
    };

    @Bean
    @Override
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        log.info("配置考试服务安全过滤链");
        
        http
            // 禁用CSRF保护
            .csrf(AbstractHttpConfigurer::disable)
            // 配置认证和授权规则
            .authorizeHttpRequests(authorize -> {
                // 明确允许API文档相关端点
                authorize.requestMatchers(AUTH_WHITELIST).permitAll();
                // 允许公开端点 - 使用统一配置
                authorize.requestMatchers(PUBLIC_ENDPOINTS).permitAll();
                // 学生角色端点
                authorize.requestMatchers(STUDENT_ENDPOINTS).hasAnyRole("STUDENT", "USER", "TEACHER", "ADMIN");
                // 教师角色端点
                authorize.requestMatchers(TEACHER_ENDPOINTS).hasAnyRole("TEACHER", "ADMIN");
                // 管理员角色端点
                authorize.requestMatchers(ADMIN_ENDPOINTS).hasRole("ADMIN");
                // 其他请求需要认证
                authorize.anyRequest().authenticated();
            })
            // 使用无状态会话
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            // 禁用OAuth2资源服务器功能
            .oauth2ResourceServer(AbstractHttpConfigurer::disable);
        
        return http.build();
    }
}
